package com.elitedatai.mchtest.map.service.impl;

import com.dji.sdk.cloudapi.device.DeviceDomainEnum;
import com.elitedatai.mchtest.common.error.CommonErrorEnum;
import com.elitedatai.mchtest.manage.model.dto.DeviceDTO;
import com.elitedatai.mchtest.manage.model.param.DeviceQueryParam;
import com.elitedatai.mchtest.manage.service.IDeviceRedisService;
import com.elitedatai.mchtest.manage.service.IDeviceService;
import com.elitedatai.mchtest.map.model.dto.DeviceDataStatusDTO;
import com.elitedatai.mchtest.map.model.dto.DeviceFlightAreaDTO;
import com.elitedatai.mchtest.map.service.IDeviceDataService;
import com.elitedatai.mchtest.map.service.IDeviceFlightAreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author sean
 * @version 1.9
 * @date 2023/11/24
 */
@Service
public class DeviceDataServiceImpl implements IDeviceDataService {

    /**
     * 设备服务接口，用于获取设备相关信息
     */
    @Autowired
    private IDeviceService deviceService;

    /**
     * 设备Redis服务接口，用于检查设备在线状态
     */
    @Autowired
    private IDeviceRedisService deviceRedisService;

    /**
     * 设备飞行区域服务接口，用于获取设备飞行区域相关信息
     */
    @Autowired
    private IDeviceFlightAreaService deviceFlightAreaService;

    /**
     * 获取工作空间内所有设备的数据状态
     *
     * @param workspaceId 工作空间ID
     * @return 设备数据状态列表
     * @throws RuntimeException 当没有找到设备时抛出异常
     */
    @Override
    public List<DeviceDataStatusDTO> getDevicesDataStatus(String workspaceId) {
        // 根据工作空间ID和设备类型（DOCK）查询设备列表
        List<DeviceDTO> devices = deviceService.getDevicesByParams(DeviceQueryParam.builder()
                .domains(List.of(DeviceDomainEnum.DOCK.getDomain())).workspaceId(workspaceId).build());

        // 检查设备列表是否为空，如果为空则抛出异常
        if (CollectionUtils.isEmpty(devices)) {
            throw new RuntimeException(CommonErrorEnum.ILLEGAL_ARGUMENT.getMessage());
        }

        // 将设备信息转换为设备数据状态DTO，并过滤掉飞行区域状态为空的设备
        return devices.stream().map(device -> DeviceDataStatusDTO.builder()
                        .deviceName(device.getDeviceName())           // 设备名称
                        .deviceSn(device.getDeviceSn())               // 设备序列号
                        .nickname(device.getNickname())               // 设备昵称
                        .online(deviceRedisService.checkDeviceOnline(device.getDeviceSn()))  // 设备在线状态
                        .flightAreaStatus(getDeviceStatus(workspaceId, device.getDeviceSn()).orElse(null))  // 飞行区域状态
                        .build())
                .filter(device -> Objects.nonNull(device.getFlightAreaStatus()))  // 过滤掉飞行区域状态为空的设备
                .collect(Collectors.toList());  // 收集结果为列表
    }

    /**
     * 根据工作空间ID和设备序列号获取设备状态
     *
     * @param workspaceId 工作空间ID
     * @param deviceSn 设备序列号
     * @return 设备飞行区域状态的可选包装对象
     */
    @Override
    public Optional<DeviceFlightAreaDTO> getDeviceStatus(String workspaceId, String deviceSn) {
        // 通过设备飞行区域服务获取设备飞行区域信息，并映射为DeviceFlightAreaDTO对象
        return deviceFlightAreaService.getDeviceFlightAreaByDevice(workspaceId, deviceSn)
                .map(area -> DeviceFlightAreaDTO.builder()
                        .syncStatus(area.getSyncStatus())   // 同步状态
                        .syncCode(area.getSyncCode())       // 同步代码
                        .syncMsg(area.getSyncMsg())         // 同步消息
                        .build());
    }
}